home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
ar
/
archiver.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-23
|
14KB
|
745 lines
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the file "../Copyright".
*/
/* ar - archiver Author: Michiel Huisjes */
/* Made into arch/aal by Ceriel Jacobs
*/
static char RcsId[] = "$Header: archiver.c,v 1.11 87/08/24 09:13:31 ceriel Exp $";
/*
* Usage: [arch|aal] [adprtvx] archive [file] ...
* v: verbose
* x: extract
* a: append
* r: replace (append when not in archive)
* d: delete
* t: print contents of archive
* p: print named files
* l: temporaries in current directory instead of /tmp
* c: don't give "create" message
#ifdef DISTRIBUTION
* D: make distribution: use distr_time, uid=2, gid=2, mode=0644
#endif
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <arch.h>
#ifdef AAL
#include <ranlib.h>
#include <out.h>
#define MAGIC_NUMBER AALMAG
long offset;
struct ranlib *tab;
long tnum = 0;
char *tstrtab;
long tssiz = 0;
char *malloc(), *realloc(), *strcpy(), *strncpy();
long lseek();
long time();
unsigned int tabsz, strtabsz;
#else
#define MAGIC_NUMBER ARMAG
#endif
#define odd(nr) (nr & 01)
#define even(nr) (odd(nr) ? nr + 1 : nr)
typedef char BOOL;
#define FALSE 0
#define TRUE 1
#define READ 0
#define APPEND 2
#define CREATE 1
#define MEMBER struct ar_hdr
#define NIL_PTR ((char *) 0)
#define NIL_MEM ((MEMBER *) 0)
#define NIL_LONG ((long *) 0)
#define IO_SIZE (10 * 1024)
#define equal(str1, str2) (!strncmp((str1), (str2), 14))
BOOL verbose;
BOOL app_fl;
BOOL ex_fl;
BOOL show_fl;
BOOL pr_fl;
BOOL rep_fl;
BOOL del_fl;
BOOL nocr_fl;
BOOL local_fl;
#ifdef DISTRIBUTION
BOOL distr_fl;
long distr_time;
#endif
int ar_fd;
char io_buffer[IO_SIZE];
char *progname;
char temp_buf[32];
char *temp_arch = &temp_buf[0];
extern char *mktemp();
extern char *ctime();
usage()
{
error(TRUE, "usage: %s %s archive [file] ...\n",
progname,
#ifdef AAL
"[acdrtxvl]"
#else
"[acdprtxvl]"
#endif
);
}
/*VARARGS2*/
error(quit, str1, str2, str3, str4)
BOOL quit;
char *str1, *str2, *str3, *str4;
{
char errbuf[256];
sprintf(errbuf, str1, str2, str3, str4);
write(2, errbuf, strlen(errbuf));
if (quit) {
unlink(temp_arch);
exit(1);
}
}
char *basename(path)
char *path;
{
register char *ptr = path;
register char *last = NIL_PTR;
while (*ptr != '\0') {
if (*ptr == '/')
last = ptr;
ptr++;
}
if (last == NIL_PTR)
return path;
if (*(last + 1) == '\0') {
*last = '\0';
return basename(path);
}
return last + 1;
}
extern unsigned int rd_unsigned2();
open_archive(name, mode)
register char *name;
register int mode;
{
unsigned short magic = 0;
int fd;
if (mode == CREATE) {
if ((fd = creat(name, 0644)) < 0)
error(TRUE, "cannot creat %s\n", name);
magic = MAGIC_NUMBER;
wr_int2(fd, magic);
return fd;
}
if ((fd = open(name, mode)) < 0) {
if (mode == APPEND) {
close(open_archive(name, CREATE));
if (!nocr_fl) error(FALSE, "%s: creating %s\n", progname, name);
return open_archive(name, APPEND);
}
error(TRUE, "cannot open %s\n", name);
}
lseek(fd, 0L, 0);
magic = rd_unsigned2(fd);
if (magic != MAGIC_NUMBER)
error(TRUE, "%s is not in ar format\n", name);
return fd;
}
catch()
{
unlink(temp_arch);
exit (2);
}
main(argc, argv)
int argc;
char *argv[];
{
register char *ptr;
progname = argv[0];
if (argc < 3)
usage();
for (ptr = argv[1]; *ptr; ptr++) {
switch (*ptr) {
case 't' :
show_fl = TRUE;
break;
case 'v' :
verbose = TRUE;
break;
case 'x' :
ex_fl = TRUE;
break;
case 'a' :
app_fl = TRUE;
break;
case 'c' :
nocr_fl = TRUE;
break;
#ifndef AAL
case 'p' :
pr_fl = TRUE;
break;
#endif
case 'd' :
del_fl = TRUE;
break;
case 'r' :
rep_fl = TRUE;
break;
case 'l' :
local_fl = TRUE;
break;
#ifdef DISTRIBUTION
case 'D' :
distr_fl = TRUE;
break;
#endif
default :
usage();
}
}
#ifdef DISTRIBUTION
if (distr_fl) {
struct stat statbuf;
stat(progname, &statbuf);
distr_time = statbuf.st_mtime;
}
#endif
if (local_fl) strcpy(temp_arch, "ar.XXXXXX");
else strcpy(temp_arch, "/tmp/ar.XXXXXX");
if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1)
usage();
if (rep_fl || del_fl
#ifdef AAL
|| app_fl
#endif
) {
mktemp(temp_arch);
}
#ifdef AAL
tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib));
tstrtab = malloc(4096);
if (!tab || !tstrtab) error(TRUE,"Out of core\n");
tabsz = 512;
strtabsz = 4096;
#endif
signal(SIGINT, catch);
get(argc, argv);
return 0;
}
MEMBER *
get_member()
{
static MEMBER member;
again:
if (rd_arhdr(ar_fd, &member) == 0)
return NIL_MEM;
#ifdef AAL
if (equal(SYMDEF, member.ar_name)) {
lseek(ar_fd, member.ar_size, 1);
goto again;
}
#endif
return &member;
}
char *get_mode();
get(argc, argv)
int argc;
register char *argv[];
{
register MEMBER *member;
int i = 0;
int temp_fd, read_chars;
ar_fd = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND);
if (rep_fl || del_fl
#ifdef AAL
|| app_fl
#endif
)
temp_fd = open_archive(temp_arch, CREATE);
while ((member = get_member()) != NIL_MEM) {
if (argc > 3) {
for (i = 3; i < argc; i++) {
if (equal(basename(argv[i]), member->ar_name))
break;
}
if (i == argc || app_fl) {
if (rep_fl || del_fl
#ifdef AAL
|| app_fl
#endif
) {
#ifdef AAL
if (i != argc) {
printf("%s: already in archive\n", argv[i]);
argv[i] = "";
}
#endif
wr_arhdr(temp_fd, member);
copy_member(member, ar_fd, temp_fd, 0);
}
else {
#ifndef AAL
if (app_fl && i != argc) {
printf("%s: already in archive\n", argv[i]);
argv[i] = "";
}
#endif
lseek(ar_fd, even(member->ar_size),1);
}
continue;
}
}
if (ex_fl || pr_fl)
extract(member);
else {
if (rep_fl)
add(argv[i], temp_fd, "r - %s\n");
else if (show_fl) {
char buf[sizeof(member->ar_name) + 2];
register char *p = buf, *q = member->ar_name;
while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) {
*p++ = *q++;
}
*p++ = '\n';
*p = '\0';
if (verbose) {
char *mode = get_mode(member->ar_mode);
char *date = ctime(&(member->ar_date));
*(date + 16) = '\0';
*(date + 24) = '\0';
printf("%s%3u/%u%7D %s %s %s",
mode,
(unsigned) (member->ar_uid & 0377),
(unsigned) (member->ar_gid & 0377),
member->ar_size,
date+4,
date+20,
buf);
}
else printf(buf);
}
else if (del_fl)
show("d - %s\n", member->ar_name);
lseek(ar_fd, even(member->ar_size), 1);
}
argv[i] = "";
}
if (argc > 3) {
for (i = 3; i < argc; i++)
if (argv[i][0] != '\0') {
#ifndef AAL
if (app_fl)
add(argv[i], ar_fd, "a - %s\n");
else
#endif
if (rep_fl
#ifdef AAL
|| app_fl
#endif
)
add(argv[i], temp_fd, "a - %s\n");
else {
printf("%s: not found\n", argv[i]);
}
}
}
if (rep_fl || del_fl
#ifdef AAL
|| app_fl
#endif
) {
signal(SIGINT, SIG_IGN);
close(ar_fd);
close(temp_fd);
ar_fd = open_archive(argv[2], CREATE);
temp_fd = open_archive(temp_arch, APPEND);
#ifdef AAL
write_symdef();
#endif
while ((read_chars = read(temp_fd, io_buffer, IO_SIZE)) > 0)
mwrite(ar_fd, io_buffer, read_chars);
close(temp_fd);
unlink(temp_arch);
}
close(ar_fd);
}
add(name, fd, mess)
char *name;
int fd;
char *mess;
{
static MEMBER member;
register int read_chars;
struct stat status;
int src_fd;
if (stat(name, &status) < 0) {
error(FALSE, "cannot find %s\n", name);
return;
}
else if ((src_fd = open(name, 0)) < 0) {
error(FALSE, "cannot open %s\n", name);
return;
}
strncpy (member.ar_name, basename (name), sizeof(member.ar_name));
member.ar_uid = status.st_uid;
member.ar_gid = status.st_gid;
member.ar_mode = status.st_mode;
member.ar_date = status.st_mtime;
member.ar_size = status.st_size;
#ifdef DISTRIBUTION
if (distr_fl) {
member.ar_uid = 2;
member.ar_gid = 2;
member.ar_mode = 0644;
member.ar_date = distr_time;
}
#endif
wr_arhdr(fd, &member);
#ifdef AAL
do_object(src_fd, member.ar_size);
lseek(src_fd, 0L, 0);
offset += AR_TOTAL + even(member.ar_size);
#endif
while (status.st_size > 0) {
i